package gui.tabs;

import gui.ActionPanel;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Iterator;

import javax.swing.*;
import javax.swing.event.ChangeEvent;

import control.ActNewListener;

import data.ActionList;
import data.ProcList;
import data.model.Action;
import data.model.Task;
import data.model.TaskGraph;

/**
 * Content for the "action tab"
 * 
 * @author Will Home
 *
 */
public class ActionTab extends AbstractTab implements ActionListener {
	 
	 private JTextArea taskDisp;
	 private JTextArea procDisp;
	
	public ActionTab()
	{
		super();
		addButtonPane("Action");
		addInfoPane();
		procDisp = addList("Processors");
		taskDisp = addList("Tasks");
		
		combo.setSelectedIndex(0);
		comboUsed();
	}
	
	@Override
	protected void addComboBox() {
		combo = new JComboBox(ActionList.getList());
		combo.removeItemAt(0);
		combo.validate();
		combo.setEditable(false);
		combo.setRenderer(new MyCellRenderer());
		combo.addActionListener(this);
	}
		
	 class MyCellRenderer extends JLabel implements ListCellRenderer {
	     public MyCellRenderer() {
	         setOpaque(true);
	     }

	     public Component getListCellRendererComponent(JList list,
	                                                   Object value,
	                                                   int index,
	                                                   boolean isSelected,
	                                                   boolean cellHasFocus) {
	    	 if(value != null)
	    		 setText(((Action) value).getActName());

	         return this;
	     }
	 }
	 
	 @Override
	 protected void newBtnPressed()
	 {
		 //clear fields and set editable
		 tex.setText("");
		 texA.setText("");
		 tex.setBackground(Color.white);
		 texA.setBackground(Color.white);
		 tex.setEditable(true);
		 texA.setEditable(true);

		 isNew = true;
	 }
	 	 
	 @Override
	 protected void editBtnPressed()
	 {
		 // set fields editable
		 tex.setBackground(Color.white);
		 texA.setBackground(Color.white);
		 tex.setEditable(true);
		 texA.setEditable(true);

		 isEdit = true;
	 }
	 
	 @Override
	 protected void remBtnPressed()
	 {
		 if(combo.getSelectedItem() != null)
		 {
			 int curID = ((Action) combo.getSelectedItem()).getActID();
			 //remove processor actions that use this
			 for(Object o: ActionList.getAction(curID).getProcs())
			 {
				 ProcList.getProc((Integer) o).removeAction(curID);
			 }
			//remove task actions that use this
			 for(Object o: ActionList.getAction(curID).getTasks())
			 {
				 Task t = TaskGraph.getTask(((Integer) o));
				 JOptionPane.showMessageDialog(null, t.getTaskName() + " action is undefined.","Done",
							JOptionPane.WARNING_MESSAGE);
				 t.setAction(0);
			 }
			 //remove selected action
			 ActionList.removeAction(curID);
			 combo.removeItem(combo.getSelectedItem());
			 combo.validate();

			 LogTab.logInput("Action: ID = " + curID + " removed");
			 ActionPanel.updateActions();
		 }
	 }

	 @Override
	 protected void savBtnPressed()
	 {
		 //if action exists, update it
		 if(isEdit){
			 if(combo.getSelectedItem() != null)
			 {
				 boolean change = false;
				 int curID = ((Action) combo.getSelectedItem()).getActID();
				 int i = combo.getSelectedIndex();
				 //change name
				 if(tex.getText() != null && ActionList.getAction(tex.getText()) == null)
				 {
					 ActionList.getAction(curID).setActName(tex.getText());
					 change = true;
					 LogTab.logInput("Action: ID = " + curID + ", name changed to " + tex.getText());
					 
				 }
				 //change description
				 if(texA.getText() != null)
				 {
					 ActionList.getAction(curID).setActDesc(texA.getText());
					 change = true;
					 LogTab.logInput("Action: ID = " + curID + ", description changed");
				 }
				 if(change)
				 {
					 //System.out.println(i);
					 combo.removeItem(combo.getSelectedItem());
					 combo.insertItemAt(ActionList.getAction(curID), i);
					 combo.validate();
				 }
				 else
					 LogTab.logInput("No Update.");
			
				 combo.setSelectedIndex(i);
				 comboUsed();
			 }
		 }

		 //if not, create new action
		 else if(isNew && ActionList.getAction(tex.getText()) == null)
		 {
			 ActionList.addAction(tex.getText()); //set name
			 ActionList.getAction(tex.getText()).setActDesc(texA.getText()); //set desc
			 combo.addItem(ActionList.getAction(tex.getText()));
			 
			 LogTab.logInput("New Action: " + tex.getText() + " created");
			 
			 combo.setSelectedItem(ActionList.getAction(tex.getText()));
				comboUsed();
		 }

		 else
			 LogTab.logInput("No Update");

		 ActionPanel.updateActions();


		 //set fields uneditable
		 tex.setBackground(uneditColour);
		 texA.setBackground(uneditColour);
		 tex.setEditable(false);
		 texA.setEditable(false);
		 isNew = false;
		 isEdit = false;
	 }

	 @Override
	 protected void comboUsed()
	 {
		 //clear fields
		 tex.setText("");
		 texA.setText("");
		 taskDisp.setText("");
		 procDisp.setText("");

		 //display selected action name and desc
		 if(combo.getSelectedItem() != null)
		 {
			 tex.setText(((Action) combo.getSelectedItem()).getActName());
			 texA.setText(((Action) combo.getSelectedItem()).getActDesc());

			 //iterate over set of associated tasks and display
			 int curID = ((Action) combo.getSelectedItem()).getActID();

			 Iterator<Integer> it = ActionList.getAction(curID).getTasks().iterator();
			 StringBuilder sb = new StringBuilder("");
			 while (it.hasNext())
			 {
				 int id = (Integer) it.next();
				 sb.append(" " + TaskGraph.getTask(id).getTaskName() + "\n");
			 }
			 taskDisp.setText(sb.toString());

			 //iterate over set of associated processors and display
			 it = ActionList.getAction(curID).getProcs().iterator();
			 sb = new StringBuilder("");
			 while (it.hasNext())
			 {
				 int id = (Integer) it.next();
				 sb.append(" " + ProcList.getProc(id).getProcName() + "\n");
			 }
			 procDisp.setText(sb.toString());
		 }
	 }

	 //	 protected void addBtnListeners()
	 //	 {
	 //		 newBtn.addActionListener(new ActNewListener(this));
	 //	 }

	 @Override
	 public void actionPerformed(ActionEvent e) {
		 if (e.getSource() == newBtn)
		 {
			 newBtnPressed();			
		 }
		 if(e.getSource() == editBtn)
		 {
			 editBtnPressed();
		 }
		 if(e.getSource() == remBtn)
		 {
			 remBtnPressed();
		 }
		 if(e.getSource() == savBtn)
		 {
			 savBtnPressed();
		 }
		 if(e.getSource() == combo)
		 {
			 comboUsed();
		 }

	 }

	 @Override
	 public void stateChanged(ChangeEvent ce) {
		 if(source.getSelectedComponent().equals(this))
			 {
				 refreshComboBox();
			 }
	 }

	 @Override
	 protected void refreshComboBox() {
		 combo.removeAllItems();
		 for(Object o : ActionList.getList())
		 {
			 combo.addItem((Action) o);
		 }
		 combo.removeItemAt(0);
		 combo.validate();
		 if(combo.getItemAt(0) != null)
		 {
			 combo.setSelectedIndex(0);
			 comboUsed();
		 }
	 }

}
